/*
 * Created on 2006-7-17
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package com.powerunion.datacollection.report.excelreport.impl;

import java.util.Stack;

import com.powerunion.datacollection.report.excelreport.base.BaseBand;
import com.powerunion.datacollection.report.excelreport.base.BaseElement;
import com.powerunion.datacollection.report.excelreport.base.BaseReportWriter;
import com.powerunion.datacollection.report.excelreport.base.ITempletContainer;
import com.powerunion.datacollection.report.excelreport.base.Parameter;
import com.powerunion.datacollection.report.excelreport.base.element.ElementFactory;
import com.powerunion.datacollection.report.excelreport.util.AnalyseTempletTool;

import jxl.Cell;
import jxl.Range;
import jxl.write.WritableCell;
import jxl.write.WritableSheet;

/**
 * 一个主从/列表风格的报表生气器实现。
 * @author juny
 */
public class ListStyleReportWriterImpl extends BaseReportWriter{
    /* (non-Javadoc)
     * @see excel.report.util.IWriter#analysisTemplet(jxl.write.WritableSheet)
     */
    public void analysisTemplet(WritableSheet sheet) throws Exception {
        WritableCell wc = null;
        String content = null;
        BaseElement element = null;
        ElementFactory factory = ElementFactory.getFactory();

        ITempletContainer container = this.getContainer();
        container.setBegin(0, -1);
        Stack baseBands = new Stack();
        ITempletContainer curContainer = container;
        BaseBand baseBand = null;
        String bandName = null;
        
        //分析模板文件
        int rows = sheet.getRows();
        int cols = 0;
        String property = null;
        for (int row = 0; row < rows; row++) {
            Cell[] cells = sheet.getRow(row);
            cols = cells.length;
            for (int col = 0; col < cols; col++) {
                wc = sheet.getWritableCell(col, row);
                content = wc.getContents();
                if (AnalyseTempletTool.isTempletElement(content)) {
                    if (AnalyseTempletTool.isBandTemplet(content)
                            || AnalyseTempletTool.isGroupTemplet(content)) {
                        property = AnalyseTempletTool.getPorperty(content,
                                AnalyseTempletTool.PROPERTY_PROPE);
                        bandName = AnalyseTempletTool.getPorperty(content,
                                AnalyseTempletTool.PROPERTY_NAME);
                        
                        if (property.equals(AnalyseTempletTool.BAND_BODY)) {
                            checkBandInstance(curContainer, row, col);
                            baseBand = (BaseBand)curContainer;
                            if(baseBand.getName().equals(bandName)){
                                baseBand.setDetail(col, row);
                            }else{
                                throw new Exception("Invalid band or group templet body tag!");
                            }
                            break;
                        }
                        
                        if (property.equals(AnalyseTempletTool.BAND_FOOT)) {
                            checkBandInstance(curContainer, row, col);
                            baseBand = (BaseBand)curContainer;
                            if(baseBand.getName().equals(bandName)){
                                baseBand.setBottom(col, row);
                            }else{
                                throw new Exception("Invalid band or group templet foot tag!");
                            }
                            break; //跳过band模板行
                        }
                        
                        if (property.equals(AnalyseTempletTool.BAND_END)) {
                            checkBandInstance(curContainer, row, col);
                            baseBand = (BaseBand)baseBands.pop();
                            if(baseBand.getName().equals(bandName) && 
                                    ((BaseBand)curContainer).getName().equals(baseBand.getName())){
                                //保存模板定义的范围信息。
                                Range range = this.getCellRange(sheet, col, row);
                                if(null != range){
                                    baseBand.setEnd(range.getBottomRight().getColumn(), 
                                            range.getBottomRight().getRow());
                                }else{
                                    baseBand.setEnd(col, row);
                                }
                                
                                if(baseBands.isEmpty()){
                                    curContainer = container;
                                }else{
                                    curContainer = (ITempletContainer)baseBands.peek();
                                }
                            }else{
                                throw new Exception("Invalid band or group templet end tag!");
                            }
                            break;//跳过band模板行
                        }
                        
                        if (property.equals(AnalyseTempletTool.BAND_HEAD)) {
                            element = factory.getElement(wc, container);
                            if(null != element){
                                ((BaseBand)element).setReportConfig(this.sheetConfig);
                                curContainer.addElement(element, col, row);
                                curContainer = (ITempletContainer)element;
                                curContainer.setBegin(col, row);
                                
                                baseBands.push(element);
                                break;//跳过band模板行
                            }
                        }
                    } else {
                        element = factory.getElement(wc, container);
                    }
                    if (null != element) {
                        curContainer.addElement((BaseElement) element, col, row);
                    }
                }
            }
        }
        //判断band带定义是否结束，否则为无效的模板定义，抛出异常
        if(!baseBands.isEmpty()){
            throw new Exception("Invalid band or group templet!");
        }
        this.getContainer().setEnd(sheet.getColumns() - 1, rows);

        /*读取模板组内的其他信息,如组内包含的图片信息,超链接信息,
         * 合并单元格信息等,因为这些信息不能通过单个单元格的拷贝操作
         * 来拷贝,只能标识出来一个一个手动拷贝.*/
        
        //读取模板内合并单元格信息
        getMergedCells(sheet);
        
        //读取模板中图片信息
        getImages(sheet);
        
        //完成模板读取工作后，调用每个模板元素出世化自己
        ((BaseElement)this.getContainer()).iniElement();
    }
    
    private void checkBandInstance(ITempletContainer container, int i, int j) throws Exception{
        if(!(container instanceof BaseBand)){
            throw new Exception("Invalid templet: row=" + i +
                    " col=" + j);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see excel.report.util.IWriter#writeData(excel.report.util.Parameter)
     */
    public void writeData(Parameter param) throws Exception {
        ITempletContainer ictr = this.getContainer();
        //设置报表数据写入的开始位置
        int beginRow = ictr.getEndRow();
        param.curRow = beginRow;
        //写模板中的数据
        ictr.write(param); 
        //删除模板信息
        deleteTemplet(param);
        //删除模板文件中的图片对象
        deleteAllTempletImages(param);
    }
}
